/**********
@name: editor组件
@describtion: props: title:字段别名 ,value: 字段值
@author:liubingye
@date:2023-02-10 18:36:37
***********/
<template>
  <div class="tinymce-box">
    <Editor
        id="myedit"
        v-model="content"
        :init="init"
        tag-name="div"
    />
    <ImageUpload v-model:showDialog="showAxupImgs" :limit="20" @getImage="insertImage"></ImageUpload>
  </div>
</template>

<script setup>

//引入tinymce编辑器
import Editor from '@tinymce/tinymce-vue'

//引入node_modules里的tinymce相关文件文件
import tinymce from 'tinymce/tinymce' //tinymce默认hidden，不引入则不显示编辑器
import 'tinymce/themes/silver'  //编辑器主题，不引入则报错
import 'tinymce/icons/default'  //引入编辑器图标icon，不引入则不显示对应图标
import 'tinymce/plugins/advlist'; //高级列表
import 'tinymce/plugins/anchor'; //锚点
import 'tinymce/plugins/autolink'; //自动链接
import 'tinymce/plugins/autoresize'; //编辑器高度自适应,注：plugins里引入此插件时，Init里设置的height将失效
import 'tinymce/plugins/autosave'; //自动存稿
import 'tinymce/plugins/charmap'; //特殊字符
import 'tinymce/plugins/code'; //编辑源码
import 'tinymce/plugins/codesample'; //代码示例
import 'tinymce/plugins/directionality'; //文字方向
import 'tinymce/plugins/emoticons'; //表情
import 'tinymce/plugins/fullpage'; //文档属性
import 'tinymce/plugins/fullscreen'; //全屏
import 'tinymce/plugins/help'; //帮助
import 'tinymce/plugins/hr'; //水平分割线
import 'tinymce/plugins/image'; //插入编辑图片
import 'tinymce/plugins/importcss'; //引入css
import 'tinymce/plugins/insertdatetime'; //插入日期时间
import 'tinymce/plugins/link'; //超链接
import 'tinymce/plugins/lists'; //列表插件
import 'tinymce/plugins/media'; //插入编辑媒体
import 'tinymce/plugins/nonbreaking'; //插入不间断空格
import 'tinymce/plugins/pagebreak'; //插入分页符
import 'tinymce/plugins/paste'; //粘贴插件
import 'tinymce/plugins/preview'; //预览
import 'tinymce/plugins/print'; //打印
import 'tinymce/plugins/quickbars'; //快速工具栏
import 'tinymce/plugins/save'; //保存
import 'tinymce/plugins/searchreplace'; //查找替换
import 'tinymce/plugins/tabfocus'; //切入切出，按tab键切出编辑器，切入页面其他输入框中
import 'tinymce/plugins/table'; //表格
import 'tinymce/plugins/template'; //内容模板
import 'tinymce/plugins/textcolor'; //文字颜色
import 'tinymce/plugins/textpattern'; //快速排版
import 'tinymce/plugins/toc'; //目录生成器
import 'tinymce/plugins/visualblocks'; //显示元素范围
import 'tinymce/plugins/visualchars'; //显示不可见字符
import 'tinymce/plugins/wordcount'; //字数统计
import '@npkg/tinymce-plugins/importword' //三方插件导入word
import '@npkg/tinymce-plugins/indent2em'

import { watch, ref } from "vue";
import {convertHexToBase64, parseRtf} from "@/utils/tools";
import {useStore} from "vuex";

const props = defineProps({
  title: {
    type: String,
    default: ''
  },
  modelValue: {
    type: String,
    default: ''
  },
  minHeight: {
    type: Number,
    default: 400
  }
})
const emits = defineEmits(['update:modelValue'])

const store = useStore()
const actionUrl = ref(store.state.content.uploadUrl)
store.dispatch('content/updateUploadUrl').then(res => {
  actionUrl.value = res.uploadUrl
})
const init = {
  language_url: process.env.BASE_URL+'tinymce/langs/zh_CN.js',  //引入语言包文件
  language: 'zh_CN',  //语言类型

  skin_url: process.env.BASE_URL+'tinymce/skins/ui/oxide',  //皮肤：浅色

  plugins: 'autoresize print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount textpattern autosave ',  //插件配置
  toolbar: ['importword axupimgs media link table | code undo redo | formatselect fontselect fontsizeselect','lineheight bullist numlist | forecolor backcolor bold italic underline strikethrough | alignleft aligncenter alignright alignjustify outdent indent indent2em | blockquote subscript superscript'],  //工具栏配置，设为false则隐藏
  menubar: 'edit insert view format tools table', //菜单栏配置，设为false则隐藏，不配置则默认显示全部菜单，也可自定义配置--查看 http://tinymce.ax-z.cn/configure/editor-appearance.php --搜索“自定义菜单”
  menu: {
    edit: { title: '编辑', items: 'undo redo | cut copy paste pastetext | selectall' },
    insert: { title: '插入', items: 'link image  |  hr' },
    view: { title: '查看', items: 'visualaid' },
  },
  min_height: props.minHeight,
  fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 48px 56px 72px',  //字体大小
  font_formats: '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;',  //字体样式
  lineheight_formats: "0.5 0.8 1 1.2 1.5 1.75 2 2.5 3 4 5",  //行高配置，也可配置成"12px 14px 16px 20px"这种形式

  placeholder: '在这里输入文字',
  branding: false,  //tiny技术支持信息是否显示
  resize: false,  //编辑器宽高是否可变，false-否,true-高可变，'both'-宽高均可，注意引号
  elementpath: false,  //元素路径是否显示
  content_css: process.env.BASE_URL+'tinymce/tinycontent.css',
  content_style: "img {max-width:100%;}",  //直接自定义可编辑区域的css样式
  paste_data_images: true,  //图片是否可粘贴
  // eslint-disable-next-line no-unused-vars
  images_upload_handler: (blobInfo, success, failure, progress) => {

    // 方法1：用base64的图片形式上传图片
    // const img = 'data:image/jpeg;base64,' + blobInfo.base64()
    // success(img)

    // 方法2：上传oos
    const xhr = new XMLHttpRequest()
    xhr.withCredentials = false
    xhr.open('POST', actionUrl.value)
    xhr.onload = function () {
      if(xhr.status === 403){
        if(process.env.NODE_ENV === 'development') console.log('HTTP Error: ' + xhr.status);
        return
      }
      if(xhr.status < 200 || xhr.status >= 300){
        if(process.env.NODE_ENV === 'development') console.log('HTTP Error: ' + xhr.status);
        return
      }
      //注意json
      const json = JSON.parse(xhr.responseText);
      if(json.url && json.url != ''){
        success(json.url);
      }
    }

    xhr.onerror = function () {
      failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status)
    }

    let formData = new FormData();
    formData.append('name', blobInfo.filename());
    formData.append('file', blobInfo.blob(), blobInfo.filename());
    xhr.send(formData);

  },
  init_instance_callback: function(editor){
    editor.on('paste', evt => {
      const clipboardData = evt.clipboardData
      const isImage = clipboardData.types.length && clipboardData.types.join('').includes('Files')
      if (!isImage) {
        //------------------------粘贴word核心代码开始-------------------------
        const hexStrings = parseRtf(evt.clipboardData.getData('text/rtf'))
        // 获取base64图片数据
        const base64Images = hexStrings.map((hexObj) => {
          return convertHexToBase64(hexObj.hex)
        })
        setTimeout(() => {
          const wordImages = tinymce.activeEditor.dom.doc.querySelectorAll('img[src*="file://"]')
          wordImages.forEach((item, index) => {
            item.src = `data:${hexStrings[index].type};base64,${base64Images[index]}`;
            tinymce.activeEditor.uploadImages()
          })
        }, 200)
        //------------------------粘贴word核心代码结束-------------------------
        return
      }
      const file = clipboardData.files[0]
      if (!file || !file.name || !(file.name.toLowerCase().indexOf('.png') !== -1 || file.name.toLowerCase().indexOf('.gif') !== -1
          || file.name.toLowerCase().indexOf('.jpeg') !== -1 || file.name.toLowerCase().indexOf('.jpg') !== -1)) {
        this.$message.error('您粘贴的不是图片请检查！')
        return
      }
      if (file.size / 1024 / 1024 > 5) {
        this.$message.error('上传失败，图片大小请控制在 5M 以内')
        return
      }
    })

  },
  setup: (editor) => {
    editor.ui.registry.addButton('axupimgs',{
      text: `<i class="iconfont">&#xe609;</i>`,
      tooltip: '批量上传',
      onAction: () => {
        showAxupImgs.value = true
      }
    })
  }
}
tinymce.init(init)

const revert_data = content => {
  emits('update:modelValue', content.value);
};
const content = ref(props.modelValue);
watch(() => props.modelValue,() => {
  content.value = props.modelValue
})
watch(
    () => content.value,
    () => {
      revert_data(content);
    },
);

const showAxupImgs = ref(false)
const insertImage = (imgList) => {
  let imgContent = ``
  imgList.forEach(item => {
    let _img = `<p><img src="${item.url}" /></p>`
    imgContent = imgContent + _img
  })
  tinymce.editors['myedit'].insertContent(imgContent+'<p></p>')
}
</script>

<style lang="scss" scoped>
.tinymce-box{
  width: 100%;
  .editor-header{
    height: 60px;
    line-height: 60px;
    h2{
      font-size: 18px;
      color: #333333;
    }
  }
}
::v-deep(.axupimg-box .el-dialog__body){
  padding: 0;
}
.axupimg-box{
  .inner-axupimg-box{
    display: flex;
    height: 450px;
    .axupimg-upload-box{
      width: 520px;
      height: 100%;
      .local-upload{
        padding: 10px;
        width: 500px;
        .local-upload-list{
          height: 330px;
          display: flex;
          flex-wrap: wrap;
          position: relative;
          align-content: flex-start;
          &>div{
            height: 110px;
            width: 110px;
            margin-right: 10px;
            margin-bottom: 10px;
            background-color: #F0F2F7;
          }
          li{
            height: 110px;
            width: 110px;
            box-sizing: border-box;
            list-style: none;
            border: 1px solid #dcdfe6;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            border-radius: 5px;
            cursor: pointer;
            .img-box{
              height: 108px;
              width: 108px;
              display: flex;
              justify-content: center;
              align-items: center;
              img{
                max-width: 108px;
                max-height: 108px;
              }
            }
            .progress-box{
              width: 100px;
              position: absolute;
              bottom: 5px;
            }
            .remove-upload{
              color: $placeholderColor;
              position: absolute;
              right: 5px;
              top: 8px;
              cursor: pointer;
              display: none;
            }
            .choose-check{
              position: absolute;
              left: 5px;top: 0;
            }
            &:hover{
              .remove-upload{
                display: block;
              }
            }
            &.is-choose{
              border-color: $mainColor;
            }
          }
        }
      }
      .online-upload{
        padding: 10px;
        width: 500px;
        .online-upload-list{
          display: flex;
          flex-wrap: wrap;
          height: 375px;
          .online-upload-item{
            height: 115px;width: 115px;
            border-radius: 6px;
            background-color: $borderColor;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-right: 10px;
            margin-bottom: 10px;
            cursor: pointer;
            box-sizing: border-box;
            img{
              max-width: 100%;
              max-height: 100%;
            }
            &:nth-child(4n){
              margin-right: 0;
            }
            &.is-choose{
              border: 1px solid $mainColor;
            }
          }
        }
      }
    }
    .axupimg-list-box{
      width: 180px;
      height: 100%;
      border-left: 1px solid #dcdfe6;
      box-sizing: border-box;
      padding: 10px;
      p{
        margin-bottom: 10px;
      }
      .chose-img-list{
        height: 400px;
        justify-content: center;
        flex-direction: column;
        .chose-img-box{
          height: 130px;width: 145px;
          display: flex;
          align-items: center;
          justify-content: center;
          background-color: #F0F2F7;
          margin-bottom: 10px;
          border-radius: 6px;
          img{
            max-height: 100%;
            max-width: 100%;
          }
        }
      }
    }
  }
}
</style>
